package com.wlyuan.open.domain.service.qifan;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wlyuan.open.domain.PushBusinessType;
import com.wlyuan.open.domain.PushTask;
import com.wlyuan.open.domain.repository.PushTaskRepository;
import com.wlyuan.open.domain.service.PushStrategy;
import com.wlyuan.open.infrastructure.config.QiFanProperties;
import com.wlyuan.open.vo.push.order.OrderDetailVO;
import com.wlyuan.open.vo.push.order.OrderGoodsVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author 起帆推送
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class QiFanPushStrategy implements PushStrategy {

    private final PushTaskRepository pushTaskRepository;
    private final QiFanProperties qiFanProperties;
    private static Pattern NUMBER_PATTERN = Pattern.compile("^-?\\d+(\\.\\d+)?$");

    @Override
    public void handle(PushTask pushTask) {
        var loginSuccess = login(pushTask);
        //如果登录成功，进行下一步
        if (loginSuccess) {
            //判断业务，如果是预签收，则走预签收接口
            if (pushTask.getBusinessType().equals(PushBusinessType.TRACK_PRE_REACH)) {
                orderPreSign(pushTask);
            } else if (pushTask.getBusinessType().equals(PushBusinessType.ORDER_SIGNED)) {
                orderSign(pushTask);
            }
        }
        pushTaskRepository.save(pushTask);

    }


    private Boolean login(PushTask pushTask) {
        JSONObject object = new JSONObject();
        //账户编码
        object.put("userId", qiFanProperties.getUserId());
        //密码
        object.put("password", qiFanProperties.getPassword());
        //客户端类型 固定为 S。
        object.put("clientType", qiFanProperties.getClientType());
        //编码 固定为空白字符串。
        object.put("epId", "");
        String body = object.toString();
        String url = qiFanProperties.getHost() + qiFanProperties.getLoginUrl();
        String loginResult = HttpUtils.qifandoPost(url, body, "Login");
        if (StringUtils.isNotEmpty(loginResult)) {
            try {
                if ((Boolean) JSON.parseObject(loginResult).get("Success")) {
                    return true;
                } else {
                    logger.info("起帆登录失败，失败原因:{},保存json格式：{}", JSON.parseObject(loginResult).get("ErrorMessage"), "保存json格式：" + body);
                    pushTask.fail(url, body, loginResult, "起帆登录失败");
                    return false;
                }
            } catch (Exception ex) {
                logger.info("起帆登录失败", ex);
                pushTask.fail(url, body, loginResult, "起帆登录失败");
            }
        }
        return false;
    }

    private String preSignAssemble(String pactCode) {
        JSONObject preSignObject = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(new PreSignRequest(pactCode, "Y"));
        preSignObject.put("orders", jsonArray);
        return preSignObject.toString();
    }

    public void orderPreSign(PushTask pushTask) {
        String requestBodyData = preSignAssemble(pushTask.getContractNo());
        String url = qiFanProperties.getHost() + qiFanProperties.getPreSignUrl();
        String result = HttpUtils.qifandoPost(url, requestBodyData, "qifan");
        try {
            if (StringUtils.isNotEmpty(result)) {
                logger.info("起帆预签收推送返回值：{}", result);
                if (result.contains("success")) {
                    JSONArray objects = JSON.parseArray(result);
                    if ((Boolean) ((JSONObject) objects.get(0)).get("success")) {
                        pushTask.success(url, requestBodyData, result);
                    } else {
                        pushTask.fail(url, requestBodyData, result, ((JSONObject) objects.get(0)).getString("errorMessage"));
                    }
                } else if (StringUtils.isNotBlank(JSON.parseObject(result).get("Message").toString())) {
                    pushTask.fail(url, requestBodyData, result, JSON.parseObject(result).getString("Message"));
                } else {
                    pushTask.fail(url, requestBodyData, result, "起帆预签收推送失败");
                }
            } else {
                pushTask.fail(url, requestBodyData, result, "起帆预签收推送失败");
            }
        } catch (Exception ex) {
            logger.error("起帆预签收推送失败：", ex);
            pushTask.fail(url, requestBodyData, result, "起帆预签收推送失败" + ex.getMessage());
        }
    }

    private String signAssemble(PushTask pushTask) {
        OrderDetailVO orderDetailVO = pushTask.getBusinessInfo().toJavaObject(OrderDetailVO.class);
        String bobys = "";
        QiFanSignRequest signRequest = new QiFanSignRequest();
        //操作 sign| 签收、cancel|取消签收，必填
        signRequest.setOperation_type("sign");
        //交货单列表
        List<QiFanSignRequest.SignOrder> orders = new ArrayList<>();

        QiFanSignRequest.SignOrder os = signRequest.new SignOrder();
        //交货单号 必填
        String pactCode = "";
        if (StringUtils.isNotBlank(orderDetailVO.getContractNo())) {
            pactCode = orderDetailVO.getContractNo();
        }
        os.setOrderNo(pactCode);

        DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        //签收日期  签收时必填
        String signDate = null;
        if (orderDetailVO.getSignTime() != null) {
            signDate = orderDetailVO.getSignTime().format(sdf);
            logger.info("起帆订单推送-签收日期：{}", signDate);
        }
        os.setSignDate(signDate);
        //回单日期  签收时必填
        String receiptData = null;
        if (orderDetailVO.getSignTime() != null) {
            receiptData = orderDetailVO.getSignTime().format(sdf);
            logger.info("起帆订单推送-回单日期：{}", receiptData);
        }
        os.setReceiptDate(receiptData);
        //签收人   签收时必填
        if (StringUtils.isNotBlank(orderDetailVO.getToAddress().getContactName())) {
            os.setSigner(orderDetailVO.getToAddress().getContactName());
        }
        //签收盖章 Y/N
        os.setStamp("Y");
        //电子签收
        os.setElecsign("Y");

        //签收明细
        os.setDetails(getSignGoods(signRequest, orderDetailVO.getGoodsList()));
        //交货单列表
        orders.add(os);
        signRequest.setOrders(orders);

        JSONObject jo = (JSONObject) JSONObject.toJSON(signRequest);
        bobys = jo.toString();
        return bobys;
    }

    public List<QiFanSignRequest.SignGoodDetail> getSignGoods(QiFanSignRequest signRequest, List<OrderGoodsVO> goodList) {
        //签收明细
        List<QiFanSignRequest.SignGoodDetail> details = new ArrayList<>();

        //收集物品集合中批次是否存在 批次带#的老数据
        List<OrderGoodsVO> batchNoList = goodList.stream().filter(a -> a.getBatchNo().contains("#")).collect(Collectors.toList());

        List<OrderGoodsVO> numberBatchNoList = goodList.stream().filter(a -> NUMBER_PATTERN.matcher(a.getBatchNo()).matches()).collect(Collectors.toList());

        Boolean batchNoFlag = false;

        if (batchNoList.size() > 0) {
            batchNoFlag = true;
        }
        //包含数字的集合必须和传入参数 数据一致，否则取集合下标+1
        if (numberBatchNoList.size() != goodList.size()) {
            batchNoFlag = true;
        }


        for (int i = 0; i < goodList.size(); i++) {
            QiFanSignRequest.SignGoodDetail signGoodDetail = signRequest.new SignGoodDetail();
            //批次包含# 老数据的情况下
            if (batchNoFlag) {
                signGoodDetail.setSequenceNum(new Float(i + 1));
            }
            //批次不包含# 新数据的情况下
            else {
                if (StringUtils.isNotBlank(goodList.get(i).getBatchNo())) {
                    //交货单序号
                    signGoodDetail.setSequenceNum(new Float(goodList.get(i).getBatchNo()));
                } else {
                    //交货单序号
                    signGoodDetail.setSequenceNum(new Float(i + 1));
                }
            }
            //客户签收数量
            if (goodList.get(i).getSign().getQuantity() != null) {
                //客户签收数量
                signGoodDetail.setSignedQuantity(goodList.get(i).getSign().getQuantity().floatValue());
            }
            //客户签收金额
            signGoodDetail.setSignedAmount(new Float(0));
            //签收说明
            if (goodList.get(i).getSign().getRemarks() != null) {
                //签收说明
                signGoodDetail.setSignedRemark(goodList.get(i).getSign().getRemarks());
            }
            details.add(signGoodDetail);
        }
        return details;
    }

    private void orderSign(PushTask pushTask) {
        String signRequestBody = signAssemble(pushTask);
        String url = qiFanProperties.getHost() + qiFanProperties.getSignUrl();
        String result = HttpUtils.qifandoPost(url, signRequestBody, "qifan");
        try {
            if (StringUtils.isNotEmpty(result)) {
                if (result.contains("success")) {
                    JSONArray objects = JSON.parseArray(result);
                    if ((Boolean) ((JSONObject) objects.get(0)).get("success")) {
                        pushTask.success(url, signRequestBody, result);
                    } else {
                        pushTask.fail(url, signRequestBody, result, ((JSONObject) objects.get(0)).getString("errorMessage"));
                    }
                } else if (StringUtils.isNotBlank(JSON.parseObject(result).get("Message").toString())) {
                    pushTask.fail(url, signRequestBody, result, JSON.parseObject(result).getString("Message"));
                } else {
                    pushTask.fail(url, signRequestBody, result, "起帆签收失败");
                }
            } else {
                pushTask.fail(url, signRequestBody, result, "起帆签收失败");
            }
        } catch (Exception ex) {
            pushTask.fail(url, signRequestBody, result, "起帆签收失败" + ex.getMessage());
            logger.error("起帆签收失败：", ex);
        }
    }

}
